package edu.mercer.sse.ldap;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;

import edu.mercer.sse.app.Config;
import edu.mercer.sse.errors.CriticalException;
import edu.mercer.sse.errors.CustomLogger;
import edu.mercer.sse.errors.ErrorLoggingVisitor;
import edu.mercer.sse.errors.LoggerCustom;

/**
 * 
 * Modify an entry to conform to LDAP schema rules.<p>
 *
 * Regular expressions optionally specified for database query columns or 
 * 	other collection.<p>
 * 
 * Example: numeric telephoneNumber. "[0-9]{3,}" as "phone-regex" in XML 
 * 	application configuration properties.<p>
 *
 * @see Config
 * 
 * @see Function
 */

public class LDAPValidateFunction

	implements Function<Map<String,String>,ImmutableMap<String,String>>
{
	
	private static final CustomLogger _log = LoggerCustom.obtainLog( 
			
			"LDAPValidateFunction", 
				
			Config.getLogLevel());	
	
	
	@Override
	public ImmutableMap<String, String> apply( final Map<String, String> 
		entry )
	{
		Map<String, String> entryValidated = new HashMap<>();

		entryValidated.putAll(entry);
		
		/* apply validation each database column */

		final Iterator<String> cols = entry.keySet().iterator();

		while( cols.hasNext() )
		{
			String column = cols.next();

			/* 
			 * remove single quotes for numeric fields, as literals can 
			 * supplement query data in layout 
			 */
			
			if( column.contains("Number") )
			{ 
				entryValidated.put( column, 
						
									entryValidated.get(column)
												  .replace("'","" ) );
				
			}//if
			
			if( Config.settings().getProperty( column + "-regex") 
					!= null )
			{ 
				try
				{
					Pattern regExPt = Pattern.compile( Config.settings()
							.getProperty( column + "-regex") );

					if( entryValidated.containsKey( column ) 

							&&

						! regExPt.matcher( entryValidated.get( column ))
								 .matches() )
					{
						_log.warning("removing invalid input: " 
								+ entryValidated.get( column ));

						entryValidated.remove( column );

					}//if

				}
				catch( final PatternSyntaxException err )
				{
					_log.severe("invalid pattern ignored in "
							+ "configuration for: " 
							+ cols.next() + "-regex");

					final CriticalException errWrapped = 
							new CriticalException( err );
					errWrapped.accept( new ErrorLoggingVisitor() );

				}//try

			}//if

		}//while
			
		return ImmutableMap.copyOf(entryValidated);

	}//method
	
	
}//class
